
import 'package:aoe_flutter/contants/constants.dart';
import 'package:aoe_flutter/service/login_control.dart';
import 'package:dio/dio.dart';
import 'package:dart_json_mapper/dart_json_mapper.dart' show JsonMapper, jsonSerializable, JsonProperty;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

import 'global.dart';

class DioClient {
  final Dio _dio = new Dio(BaseOptions(
    connectTimeout: 20000,
    receiveTimeout: 40000,
    responseType: ResponseType.json,
  ));

  Global _global;

  Future<ResponseBody> post(url, {params}) async {
    _global = await Global.getInstance();
    _dio.options.headers = _headers();
    _dio.options.queryParameters = _queryParameters();
    _dio.options.baseUrl = _global.baseUrl;

    Response<Map<String, dynamic>> response;
    try {
      response = await _dio.post(url, data: params);
      print(response);
    } on DioError catch (e, stacktrace) {
      print(e);
      print(stacktrace);
      return ResponseBody(
        success: false,
        title: '网络错误',
        error: e.toString(),
      );
    }
    if (response != null) {
      Map<String, dynamic> respData = JsonMapper.deserialize(response.data);
      ResponseBody responseBody =
          JsonMapper.deserialize<ResponseBody>(respData);
       responseBody._data = respData['result'] ;
      print(responseBody._data);
      if (responseBody.token != null) {
        _global.setToken(responseBody.token);
      }
      if (responseBody.resend ?? false) {
        return post(url, params: params);
      }
      if (responseBody.reLogin ?? false) {
        LoginControl.getInstance().logOut();
      }
      return responseBody;
    } else {
      return ResponseBody(
        success: false,
        title: '网络错误',
      );
    }
  }

  Future<ResponseBody> get(url, {params}) async {
    _global = await Global.getInstance();
    _dio.options.headers = _headers();
    _dio.options.queryParameters = _queryParameters();
    _dio.options.baseUrl = _global.baseUrl;

    Response<Map<String, dynamic>> response;
    try {
      response = await _dio.get(url, queryParameters: params);
    } on DioError catch (e, stacktrace) {
      print(e);
      print(stacktrace);
      return ResponseBody(
        success: false,
        title: '网络错误',
        error: e.toString(),
      );
    }
    if (response != null) {
      Map<String, dynamic> respData = JsonMapper.deserialize(response.data);
      ResponseBody responseBody =
          JsonMapper.deserialize<ResponseBody>(respData);
      responseBody._data = respData['result'];
      if (responseBody.token != null) {
        _global.setToken(responseBody.token);
      }
      if (responseBody.resend ?? false) {
        return get(url, params: params);
      }
      if (responseBody.reLogin ?? false) {
        LoginControl.getInstance().logOut();
      }
      return responseBody;
    } else {
      return ResponseBody(
        success: false,
        title: '网络错误',
      );
    }
  }

  Future download(BuildContext context, url,
      {Map<String, dynamic> queryParameters,
      @required path,
      ProgressCallback onReceiveProgress}) async {
    _global = await Global.getInstance();
    _dio.options.headers = _headers();
    _dio.options.queryParameters = _queryParameters();
    _dio.options.baseUrl = _global.baseUrl;
    _dio.options.responseType = ResponseType.stream;

    try {
      await _dio.download(url, path,
          queryParameters: queryParameters,
          onReceiveProgress: onReceiveProgress);
    } on DioError catch (e) {
      print(e);
    }
  }

  Map<String, dynamic> _headers() {
    return {
      REQUEST_HEADER_TOKEN_KEY: 'Bearer ' + _global.token,
      // REQUEST_HEADER_SERIAL_KEY: App.getInstance().androidInfo.androidId,
      // REQUEST_HEADER_APP_ID_KEY: App.getInstance().appId,
    };
  }

  Map<String, dynamic> _queryParameters() {
    return {
      REQUEST_PARAM_TOKEN_KEY: _global.token,
    };
  }
}

@jsonSerializable
class ResponseBody {
  final bool success;
  final String category;
  @JsonProperty(ignore: true)
  dynamic _data;
  @JsonProperty(ignore: true)
  dynamic _total;
  final String title;
  final String error;
  final bool resend;
  final String token;
  final bool reLogin;

  // @jsonConstructor
  ResponseBody({
    this.success,
    this.category,
    this.title,
    this.error,
    this.resend,
    this.token,
    this.reLogin,
  });

  T data<T>() => JsonMapper.deserialize<T>(_data);

  List<T> dataList<T>() {
    _total=_data['total'];
    List<T> result = [];
    _data['data'].forEach((i) => result.add(JsonMapper.deserialize<T>(i)));
    return result;
  }

  dynamic resultData() {
    return _data;
  }
}
